package com.shopping.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.Key;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;

@Slf4j
@Component
public class JwtUtil {

    private final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    // 生成 JWT，并在载荷中包含角色
    public String generateToken(String username, String role, int customerId) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("role", role); // 在 JWT 中存储用户角色信息
        claims.put("customerId", customerId); // 在 JWT 中存储顾客ID
        return createToken(claims, username);
    }

    // 生成令牌的具体方法
    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)  // 载荷
                .setSubject(subject)  // 主题，通常是用户名
                .setIssuedAt(new Date(System.currentTimeMillis()))  // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 设置过期时间 10小时
                .signWith(SECRET_KEY)  // 使用HS256算法和密钥签名
                .compact();  // 压缩并生成JWT
    }

    // 验证 JWT
    public Boolean validateToken(String token, String username) {
        final String extractedUsername = extractUsername(token);
        return (extractedUsername.equals(username) && !isTokenExpired(token));
    }

    // 从 JWT 中提取用户名
    public String extractUsername(String token) {
        return extractAllClaims(token).getSubject();
    }
    // 从 JWT 中提取身份
    public String extractUserRole(String token) {
        return extractAllClaims(token).get("role", String.class);
    }
    // 从 JWT 中提取顾客ID
    public Integer extractCustomerId(String token) {
        return extractAllClaims(token).get("customerId", Integer.class);
    }
    // 从 JWT 中提取所有声明
    private Claims extractAllClaims(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }

    // 检查 JWT 是否过期
    private Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    // 提取过期时间
    public Date extractExpiration(String token) {
        return extractAllClaims(token).getExpiration();
    }
}